/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package deviceManagement;

import java.util.LinkedList;
import java.util.Queue;

/**
 *
 * @author Administrator
 */
public class DeviceManager {

    public Device A1;      //A 设备 1 个，B 设备2 个， C 设备 2 个
    public Device B1;
    public Device B2;
    public Device C1;
    public Device C2;
    int[] A_DAT;      //A设备分配表  device allocation table
    int[] B2_DAT;      //B设备分配表  device allocation table
    int[] C2_DAT;      //C设备分配表  device allocation table
   
    Queue<Process> wait = new LinkedList<>();//设备等待队列
    
    public DeviceManager() {
        A_DAT = new int[1];
        B2_DAT = new int[2];
        C2_DAT = new int[2];
        A1 = new A();
        B1 = new B();
        B2 = new B();
        C1 = new C();
        C2 = new C();
        A1.work=B1.work=C1.work=B2.work=C2.work=false;
    }

    public void distribute(Device K) {   //分配设备
        K.work = true;
    }

    public void recycle(Device K) {      //回收设备
        K.work = false;
    }

    public void deadlockPrevention(processManagement.Process process) {   //死锁预防算法（采用破坏不可抢占条件）    
            
            if (A_DAT[0] == process.ID) {
                A_DAT[0] = -1;
                A1.work = false;
            }  
            
            if (B2_DAT[0] == process.ID) {
                B2_DAT[0] = -1;
                B1.work = false;
            }  
            if (B2_DAT[1] == process.ID) {
                B2_DAT[1] = -1;
                B2.work = false;
            }   
            
            if (C2_DAT[0] == process.ID) {
                C2_DAT[0] = -1;
                C1.work = false;
            }
            if (C2_DAT[1] == process.ID) {
                C2_DAT[1] = -1;
                C2.work = false;
            }   
        
    }

    public boolean isAllowProcess(processManagement.Process process) { 
//判断进程是否能申请到设备，true代表进程申请到需要的设备，false代表申请不到

        if (process.device[0] == 1) {
            if (A1.work == false) {
                A_DAT[0] = process.ID;
                A1.work = true;
            } else {
                deadlockPrevention(process);
                return false;
            }
        }

        if (process.device[1] == 1) {
            if (B1.work == false) {
                B2_DAT[0] = process.ID;
                B1.work = true;
            } else if (B2.work == false) {
                B2_DAT[1] = process.ID;
                B2.work = true;
            } else {
                deadlockPrevention(process);
                return false;
            }
        } else if (process.device[1] == 2) {
            if (B1.work == false && B2.work == false) {
                B2_DAT[0] = process.ID;
                B2_DAT[1] = process.ID;
                B1.work = true;
                B2.work = true;
            } else {
                deadlockPrevention(process);
                return false;
            }
        }

        if (process.device[2] == 1) {
            if (C1.work == false) {
                C2_DAT[0] = process.ID;
                C1.work = true;
            } else if (C2.work == false) {
                C2_DAT[1] = process.ID;
                C2.work = true;
            } else {
                deadlockPrevention(process);
                return false;
            }
        } else if (process.device[2] == 2) {
            if (C1.work == false && C2.work == false) {
                C2_DAT[0] = process.ID;
                C2_DAT[1] = process.ID;
                C1.work = true;
                C2.work = true;
            } else {
                deadlockPrevention(process);
                return false;
            }
        }
        return true;
    }

    public void Recover(processManagement.Process p) {  //销毁进程时调用此方法，回收设备    

        if (p.device[0] == 1 && A_DAT[0] == p.ID) {
            A_DAT[0] = -1;
            A1.work = false;
        }

        if (p.device[1] == 1) {
            if(B1.work = true&&B2_DAT[0] == p.ID){
               B2_DAT[0] = -1;
               B1.work = false;
            }else if(B2.work = true&&B2_DAT[1] == p.ID){
               B2_DAT[1] = -1;
               B2.work = false;
            }        
        } else if (p.device[1] == 2&&B2_DAT[0] == p.ID&&B2_DAT[1] == p.ID) {
            B2_DAT[0] = -1;
            B2_DAT[1] = -1;
            B1.work = false;
            B2.work = false;
        }

        if (p.device[2] == 1) {
            if(C1.work = true&&C2_DAT[0] == p.ID){
               C2_DAT[0] = -1;
               C1.work = false;
            }else if(C2.work = true&&C2_DAT[1] == p.ID){
               C2_DAT[1] = -1;
               C2.work = false;
            }        
        } else if (p.device[2] == 2&&C2_DAT[0] == p.ID&&C2_DAT[1] == p.ID) {        
            C2_DAT[0] = -1;
            C2_DAT[1] = -1;
            C1.work = false;
            C2.work = false;
        }
    }


    public void Refresh(processManagement.Process p) {  //阻塞进程时调用此方法，不执行任何操作
    }
}
